﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZyGames.DZPocker.Model;
using ZyGames.DZPocker.Tools;
using ZyGames.Framework.Common;

namespace ZyGames.DZPocker.Bll.Logic
{
	/// <summary>
	/// 牌型规则
	/// </summary>
	public class CardRole
	{
		public int MAX_CENTERCOUNT = 5;
		public int MAX_COUNT = 2;
		/// <summary>
		/// 全牌树木
		/// </summary>
		public int FULL_COUNT = 52;
		/// <summary>
		/// 获取牌面花色
		/// </summary>
		/// <param name="card"></param>
		/// <returns></returns>
		public CardColor GetCardColor(int card)
		{
			return (CardColor)Math.Floor((double)card / 100);
		}



		/// <summary>
		/// 获取牌面大小
		/// </summary>
		/// <param name="card"></param>
		/// <returns></returns>
		public int GetCardSize(int card)
		{
			return card % 100;
		}

		/// <summary>
		/// 牌面从小到大排序
		/// </summary>
		/// <param name="cards"></param>
		public void SortCard(int[] cards)
		{
			Array.Sort(cards, (a, b) =>
			{
				int result = (a % 100) - (b % 100);
				if (result == 0)
				{
					result = (a / 100) - (b / 100);
				}
				return result;
			});
		}

		/// <summary>
		/// 牌面从小到大排序
		/// </summary>
		public void SortCard(List<int> cards)
		{
			//面大小排序
			cards.QuickSort((a, b) =>
			{
				int result = (a % 100) - (b % 100);
				if (result == 0)
				{
					result = (a / 100) - (b / 100);
				}
				return result;
			});
		}

		/// <summary>
		/// 分组牌面大小
		/// [203,403,405,103]=> [0:[],1:[],2:[],3:[203,403,103],4:[],5:[405]]
		/// </summary>
		/// <param name="cards"></param>
		public CardGroup ParseCardGroup(int[] cards)
		{
			int len = cards.Length;
			CardGroup cardGroup = new CardGroup();
			while (len-- > 0)
			{
				int card = cards[len];
				int val = GetCardSize(card);
				cardGroup.Add(card, (CardSize)val, GetCardColor(card));
			}
			return cardGroup;
		}

		/// <summary>
		/// 是否是一对
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsOneDouble(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			//判断是否是一对的时候肯定判断过是否是两对以上，所以这里指可能是一对的可能
			var list = groupObj.FindSame(2);
			if (list.Length > 0)
			{
				cardSizes[0] = GetCardSize(list[0]);
				for (int i = 2; i < 5; i++)
				{
					for (int j = cards.Length; j > 0; j--)
					{
						var cardValue = GetCardSize(cards[j - 1]);
						if (cardValue != cardSizes[0])
							cardSizes[i] = cardValue;
					}
				}
				return true;
			}
			return false;
		}

		/// <summary>
		/// 是否是两对
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsTwoDouble(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var lists = groupObj.FindSameCountAndGroup(2);
			//可能是三对子,要挑选出两对大的出来
			if (lists.Count >= 2)
			{
				if (lists.Count == 2)
				{
					var val1 = GetCardSize(lists[0][0]);
					var val2 = GetCardSize(lists[1][0]);
					if (val1 > val2)
					{
						cardSizes[0] = val1;
						cardSizes[2] = val2;
					}
					else
					{
						cardSizes[2] = val1;
						cardSizes[0] = val2;
					}
					//从剩下来的里面选择一个最大的单牌
					for (int i = cards.Length - 1; i > 0; i--)
					{
						if (GetCardSize(cards[i]) != val1 || GetCardSize(cards[i]) != val2)
						{
							cardSizes[4] = GetCardSize(cards[i]);
						}
					}
				}
				else //三对
				{
					var s1 = GetCardSize(lists[0][0]);
					var s2 = GetCardSize(lists[1][0]);
					var s3 = GetCardSize(lists[2][0]);
					int min = (s1 < s2 && s1 < s3) ? s1 : (s2 < s3 ? s2 : s3);
					if (min == s1)
					{
						if (s2 > s3)
						{
							cardSizes[0] = s2;
							cardSizes[2] = s3;
						}
						else
						{
							cardSizes[0] = s3;
							cardSizes[2] = s2;
						}
					}
					else if (min == s2)
					{
						if (s1 > s3)
						{
							cardSizes[0] = s1;
							cardSizes[2] = s3;
						}
						else
						{
							cardSizes[0] = s3;
							cardSizes[2] = s1;
						}
					}
					else if (min == s3)
					{
						if (s1 > s2)
						{
							cardSizes[0] = s1;
							cardSizes[2] = s2;
						}
						else
						{
							cardSizes[0] = s2;
							cardSizes[2] = s1;
						}
					}
					//从剩下来的里面选择一个最大的单牌
					for (int i = cards.Length - 1; i > 0; i--)
					{
						if (GetCardSize(cards[i]) != cardSizes[0] || GetCardSize(cards[i]) != cardSizes[1])
						{
							cardSizes[4] = GetCardSize(cards[i]);
						}
					}
				}
				return true;
			}
			return false;
		}

		/// <summary>
		/// 是否是三条
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsThree(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var list = groupObj.FindSame(3);
			if (list.Length > 0)
			{
				cardSizes[0] = GetCardSize(list[0]);
			}
			return false;
		}

		/// <summary>
		/// 是否是顺子(传进来的参数已经是排序好了的,并且是从小到达)
		/// </summary>
		/// <param name="cards"></param>
		/// /// <param name="cardMaxSize">顺子的最大牌</param>
		/// <returns></returns>
		public bool IsStraight(int[] cards, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var len = cards.Length;
			if (len < 5)
				return false;
			//七张牌里选择五张判断是否是顺子
			int val1, val2;
			bool isNeedAntitone = false;
			for (var i = 0; i < 4; i++)
			{
				val1 = GetCardSize(cards[i]);
				val2 = GetCardSize(cards[i + 1]);
				if (val1 != val2 - 1)
				{
					isNeedAntitone = true;
					break;
				}
			}
			if (isNeedAntitone)
			{
				for (var j = len; j > len - 4; j--)
				{
					val1 = GetCardSize(cards[j - 1]);
					val2 = GetCardSize(cards[j - 2]);
					if (val1 - 1 != val2)
					{
						return false;
					}
				}
				cardSizes[0] = GetCardSize(cards[len - 1]);
			}
			if (!isNeedAntitone)
			{
				cardSizes[0] = GetCardSize(cards[4]);
			}
			return true;
		}

		/// <summary>
		/// 是否是同花
		/// </summary>
		/// <param name="cards"></param>
		/// <param name="groupObj"></param>
		/// <param name="cardSize">返回是一个排序好了的数组</param>
		/// <returns></returns>
		public bool IsFlush(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var list = groupObj.GetSameColorGroupByMinNum(5);
			//从小到大排序
			SortCard(list);
			if (list.Length > 0)
			{
				//大于五张，从倒数开始选择五张
				if (list.Length > 5)
				{
					for (int i = list.Length, j = 0; i > list.Length - 5; i--, j++)
					{
						cardSizes[j] = GetCardSize(cards[i - 1]);
					}
				}
				//正好等于五张
				else
				{
					for (int i = 0; i < 5; i++)
					{
						cardSizes[i] = GetCardSize(cards[4 - i]);
					}
				}
				return true;
			}
			return false;
		}

		/// <summary>
		/// 是否是葫芦(三张带一对)
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsCalabash(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var threeList = groupObj.FindSame(3);
			if (threeList.Length <= 0)
				return false;
			cardSizes[0] = GetCardSize(threeList[0]);
			int[] newCardSizes;
			bool isOnePair = IsOneDouble(cards, groupObj, out newCardSizes);
			if (!isOnePair)
				return false;
			cardSizes[3] = newCardSizes[0];
			return true;
		}

		/// <summary>
		/// 是否是金钢(四条)
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsBomb(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			var list = groupObj.FindSame(4);
			if (list.Length > 0)
			{
				cardSizes[0] = GetCardSize(list[0]);
				return true;
			}
			return false;
		}

		/// <summary>
		/// 是否是同花顺
		/// </summary>
		/// <param name="cards"></param>
		/// <param name="groupObj"></param>
		/// <param name="cardSize">返回的五张牌组</param>
		/// <returns></returns>
		public bool IsFlushSequence(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			//判断是否是同花
			if (IsFlush(cards, groupObj, out cardSizes))
			{
				//判断是否是顺子
				int[] newCardSizes;
				if (IsStraight(cards, out newCardSizes))
				{
					cardSizes[0] = newCardSizes[0];
					return true;
				}
			}
			return false;
		}

		/// <summary>
		/// 是否是皇家同花顺
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		public bool IsKingSequence(int[] cards, CardGroup groupObj, out int[] cardSizes)
		{
			cardSizes = new int[5] { 0, 0, 0, 0, 0 };
			if (IsFlushSequence(cards, groupObj, out cardSizes))
			{
				//判断最大的值是否是A
				return GetCardSize(cardSizes[0]) == (int)CardSize.C_A;
			}
			return false;
		}

		/// <summary>
		/// 获得牌型
		/// </summary>
		/// <param name="cards"></param>
		/// <param name="cardSize">返回最有价值的五张牌</param>
		/// <returns></returns>
		public DeckType GetCardType(int[] cards, out int[] cardSize)
		{
			this.SortCard(cards);
			cardSize = new int[5] { 0, 0, 0, 0, 0 };
			//将牌分组
			var groupObj = ParseCardGroup(cards);
			int val;
			int length = cards.Length;
			//牌型对比的数量不对
			if (length < 5 || length > 7)
				return DeckType.Error;

			//判断是否是皇家同花顺
			if (IsKingSequence(cards, groupObj, out cardSize))
			{
				return DeckType.KingSequence;
			}
			//判断是否是同花顺
			else if (IsFlushSequence(cards, groupObj, out cardSize))
			{
				return DeckType.FlushSequence;
			}
			//判断是否是金刚
			else if (IsBomb(cards, groupObj, out cardSize))
			{
				return DeckType.Bomb;
			}
			//判断是否是葫芦
			else if (IsCalabash(cards, groupObj, out cardSize))
			{
				return DeckType.Calabash;
			}
			//判断是否是同花
			else if (IsFlush(cards, groupObj, out cardSize))
			{
				return DeckType.Flush;
			}
			//判断是否是顺子
			else if (IsStraight(cards, out cardSize))
			{
				return DeckType.Straight;
			}
			//是否是三条
			else if (IsThree(cards, groupObj, out cardSize))
			{
				return DeckType.Three;
			}
			//是否是两对
			else if (IsTwoDouble(cards, groupObj, out cardSize))
			{
				return DeckType.TwoDouble;
			}
			//是否是一对
			else if (IsOneDouble(cards, groupObj, out cardSize))
			{
				return DeckType.OneDouble;
			}
			return DeckType.None;
		}

		/// <summary>
		/// 分析扑克
		/// </summary>
		/// <param name="cardData"></param>
		/// <param name="cardCount"></param>
		/// <param name="analyseResult"></param>
		public void AnalysebCardData(int[] cardData, int cardCount, ref AnalyseResult analyseResult)
		{
			for (int i = 0; i < cardCount; i++)
			{
				int sameCount = 1;
				var sameCardData = new int[4] { cardData[i], 0, 0, 0 };
				var logicValue = this.GetCardSize(cardData[i]);
				//获得同牌
				for (int j = i + 1; j < cardCount; j++)
				{
					//逻辑对比
					if (this.GetCardSize(cardData[j]) != logicValue)
						break;
					sameCardData[sameCount++] = cardData[j];
				}

				//保存结果
				switch (sameCount)
				{
					case 1:
						{
							analyseResult.OneLogicVolue[analyseResult.OneCount] = logicValue;
							for (int m = 0; m < sameCardData.Length; m++)
							{
								var value = sameCardData[m];
								if (value == 0)
									break;
								analyseResult.OneCardData[analyseResult.OneCount * sameCount + m] = value;
							}
							analyseResult.OneCount++;
							break;
						}
					case 2:
						{
							analyseResult.TwoLogicVolue[analyseResult.TwoCount] = logicValue;
							for (int m = 0; m < sameCardData.Length; m++)
							{
								var value = sameCardData[m];
								if (value == 0)
									break;
								analyseResult.TwoCardData[analyseResult.TwoCount * sameCount + m] = value;
							}
							analyseResult.TwoCount++;
							break;
						}
					case 3:
						{
							analyseResult.ThreeLogicVolue[analyseResult.ThreeCount] = logicValue;
							for (int m = 0; m < sameCardData.Length; m++)
							{
								var value = sameCardData[m];
								if (value == 0)
									break;
								analyseResult.ThreeCardData[analyseResult.ThreeCount * sameCount + m] = value;
							}
							analyseResult.ThreeCount++;
							break;
						}
					case 4:
						{
							analyseResult.ForLogicVolue[analyseResult.ForCount] = logicValue;
							for (int m = 0; m < sameCardData.Length; m++)
							{
								var value = sameCardData[m];
								if (value == 0)
									break;
								analyseResult.ForCardData[analyseResult.ForCount * sameCount + m] = value;
							}
							analyseResult.ForCount++;
							break;
						}
				}
				i += sameCount - 1;
			}
		}

		/****************************************************************************************************/

		/// <summary>
		/// 是否是同一花色
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		private bool IsSameCardColor(List<int> cards)
		{
			var count = cards.Count;
			var color = this.GetCardColor(cards[0]);
			for (int i = 1; i < count; i++)
			{
				if (this.GetCardColor(cards[i]) != color)
					return false;
			}
			return true;
		}

		/// <summary>
		/// 给定的牌是否是顺子
		/// </summary>
		/// <param name="cards"></param>
		/// <returns></returns>
		private bool IsGroupStraight(List<int> cards)
		{
			int[] size;
			return this.IsStraight(cards.ToArray(), out size);
		}

		/// <summary>
		/// 是否可以组成一对
		/// </summary>
		/// <param name="cards"></param>
		/// <param name="card"></param>
		/// <returns></returns>
		private bool IsPair(List<int> cards, int card)
		{
			var count = cards.Count;
			if (count <= 0)
				return false;
			var cardValue = this.GetCardSize(card);
			foreach (var cardNum in cards)
			{
				if (cardValue == this.GetCardSize(cardNum))
					return true;
			}
			return false;
		}

		/// <summary>
		/// 当前牌是否可以添加到现有的牌中
		/// </summary>
		/// <param name="UserCards"></param>
		/// <param name="card"></param>
		/// <returns></returns>
		private Dictionary<int, List<int>> CanAddCardIntoHandCards(Dictionary<int, List<int>> UserCards, int card)
		{
			var tempUserCards = new Dictionary<int, List<int>>();
			foreach (var pair in UserCards)
			{
				var list = new List<int>();
				list.AddRange(pair.Value);
				tempUserCards.Add(pair.Key, list);
			}
			var result = true;
			foreach (var userCardData in tempUserCards) //玩家的手牌
			{
				var cardsList = userCardData.Value;
				var tempData = new List<int>();
				tempData.AddRange(cardsList);
				if (this.IsPair(cardsList, card))
				{
					result = false;
					break;
				}
				else
				{
					tempData.Add(card);
					//是否是同花
					if (this.IsSameCardColor(tempData))
					{
						result = false;
						break;
					}
					//是否是顺子
					else if (this.IsGroupStraight(cardsList))
					{
						result = false;
						break;
					}
				}
			}
			if (result)
			{
				var resultUserCards = new Dictionary<int, List<int>>();
				foreach (var cardsPair in tempUserCards)
				{
					cardsPair.Value.Add(card);
					resultUserCards.Add(cardsPair.Key, cardsPair.Value);
				}
				return resultUserCards;
			}
			else
				return null;
		}

		/// <summary>
		/// 计算桌子已经发了起码三张牌的outs数量
		/// </summary>
		/// <param name="posId">领先玩家PodId</param>
		/// <param name="cardDatas">所有玩家的手牌</param>
		/// <param name="tableCard">当前桌子上的牌</param>
		/// <param name="backUpCardData">剩下的没有发的手牌</param>
		/// <returns>返回outs列表，如果没有找到则返回null</returns>
		/// <returns></returns>
		public List<int> GetInsuranceCardsMoreThanFive(int posId, Dictionary<int, List<int>> cardDatas, List<int> tableCard, List<int> backUpCardData)
		{
			var outsList = new List<int>();
			var TempUserCards = new Dictionary<int, List<int>>();
			foreach (var pair in cardDatas)
			{
				var list = new List<int>();
				list.AddRange(pair.Value);
				TempUserCards.Add(pair.Key, list);
			}
			//桌子未发的牌
			var tempBackUpCardData = new List<int>();
			tempBackUpCardData.AddRange(backUpCardData);

			//临时牌数据
			var newTempBackUpCardData = new List<int>();
			var newTableCards = new List<int>();

			//选择下一张牌，然后剩下的自由组合，只要能超过当前领先的玩家的就是outs
			foreach (var card in tempBackUpCardData)
			{
				//发一张新牌剩余没发的牌
				newTempBackUpCardData.Clear();
				newTempBackUpCardData.AddRange(tempBackUpCardData);
				newTempBackUpCardData.Remove(card);
				//新桌子上的牌
				newTableCards.Clear();
				newTableCards.AddRange(tableCard);
				newTableCards.Add(card);

				//比牌
				Dictionary<int, DeckType> cardsType = new Dictionary<int, DeckType>();
				Dictionary<int, List<int>> userCardsDic = new Dictionary<int, List<int>>();
				foreach (var pair in TempUserCards)
				{
					var pid = pair.Key;
					var cards = pair.Value;
					var lastCardData = new int[MAX_CENTERCOUNT];
					var tempType = FiveFromOther(cards.ToArray(), MAX_COUNT, newTableCards.ToArray(), newTableCards.Count, ref lastCardData, MAX_CENTERCOUNT);
					cardsType.Add(pid, tempType);
					userCardsDic.Add(pid, lastCardData.ToList());
				}

				List<int> winnerCardsList;
				bool isThisCardIsOuts = false;
				//比较大小，如果当前No1输了，则是outs牌
				if (userCardsDic.TryGetValue(posId, out winnerCardsList))
				{
					foreach (var uCardsPair in userCardsDic)
					{
						var pos = uCardsPair.Key;
						var cardsList = uCardsPair.Value;
						if (pos != posId)
						{
							//先比较牌型
							if ((int)cardsType[pos] > (int)cardsType[posId])
							{
								isThisCardIsOuts = true;
								break;
							}
							else if ((int)cardsType[pos] == (int)cardsType[posId])
							{
								if (CompareCard(cardsList.ToArray(), winnerCardsList.ToArray(), MAX_CENTERCOUNT) == 2) //前面一个是落后玩家,并且这时候大
								{
									isThisCardIsOuts = true;
									break;
								}
							}
						}
					}
				}
				else
				{
					Tool.WriteErrorLine("没有找到当前领先的玩家牌");
					return null;
				}

				if (isThisCardIsOuts)
				{
					outsList.Add(card);
				}
			}

			if (outsList.Count == 0)
			{
				Tool.WriteErrorLine("没有找到outs牌");
				return null;
			}
			return outsList;
		}

		/// <summary>
		/// 计算outs数量
		/// </summary>
		/// <param name="posId">领先玩家PodId</param>
		/// <param name="cardDatas">所有玩家的手牌</param>
		/// <param name="tableCard">当前桌子上的牌</param>
		/// <param name="backUpCardData">剩下的没有发的手牌</param>
		/// <returns>返回outs列表，如果没有找到则返回null</returns>
		public List<int> GetInsuranceCardsLessThanFive(int posId, Dictionary<int, List<int>> cardDatas, List<int> tableCard, List<int> backUpCardData)
		{
			//测试顺子
			//var tlist = new List<int>();
			//tlist.Add(310);
			//tlist.Add(311);
			//tlist.Add(312);
			//tlist.Add(313);
			//tlist.Add(314);
			//var tt = GetCardsType(tlist.ToArray(), MAX_CENTERCOUNT);

			#region 测试
			//backUpCardData.AddRange(tableCard);
			//foreach (var cards in cardDatas)
			//{
			//	backUpCardData.AddRange(cards.Value);
			//}
			////测试用
			//tableCard.Clear();
			//tableCard.Add(308);  
			#endregion
			



			var outsList = new List<int>();
			var TempUserCards = new Dictionary<int, List<int>>();


			#region 测试
			//测试
			//foreach (var pair in cardDatas)
			//{
			//	//测试用
			//	if (pair.Key == posId)
			//		TempUserCards.Add(pair.Key, new List<int>() { 302, 108 });
			//	else
			//		TempUserCards.Add(pair.Key, new List<int>() { 212, 211 });
			//}
			//backUpCardData.Remove(308);
			//backUpCardData.Remove(212);
			//backUpCardData.Remove(211);
			//backUpCardData.Remove(302);
			//backUpCardData.Remove(108); 
			#endregion



			foreach (var pair in cardDatas)
			{
				TempUserCards.Add(pair.Key, pair.Value);
			}
			//桌子未发的牌
			var tempBackUpCardData = new List<int>();
			tempBackUpCardData.AddRange(backUpCardData);
			
			//临时牌数据
			var newTempBackUpCardData = new List<int>();
			var newTableCards = new List<int>();
			
			//选择下一张牌，然后剩下的自由组合，只要能超过当前领先的玩家的就是outs
			foreach(var card in tempBackUpCardData)
			{
				//发一张新牌剩余没发的牌
				newTempBackUpCardData.Clear();
				newTempBackUpCardData.AddRange(tempBackUpCardData);
				newTempBackUpCardData.Remove(card);
				//新桌子上的牌
				newTableCards.Clear();
				newTableCards.AddRange(tableCard);


				//比牌
				Dictionary<int, DeckType> cardsType;
				//获得新的五张手牌数据
				var tempUserCardsDic = CombineMinFiveCards(TempUserCards, newTableCards, newTempBackUpCardData, out cardsType);


				cardsType.Clear();
				var newTempTableCards = new List<int>();
				newTempTableCards.AddRange(newTableCards);
				newTempTableCards.Add(card);
				//将card添加进入  选出最大的五张牌 然后再比较
				var userCardsDic = new Dictionary<int, List<int>>();
				foreach (var pair in tempUserCardsDic)
				{
					var pid = pair.Key;
					var cards = pair.Value;
					//去掉最后一张，加上现在的card
					var list = new List<int>();
					for (int i = 0; i < 4; i++ )
					{
						list.Add(cards[i]);
					}

					list.Add(card);
					//重新计算修改之后的cardsType
					var t = GetCardsType(list.ToArray(), MAX_CENTERCOUNT);
					cardsType.Add(pair.Key, t);
					userCardsDic.Add(pair.Key, list);
				}

				List<int> winnerCardsList;
				bool isThisCardIsOuts = false;
				//比较大小，如果当前No1输了，则是outs牌
				if(userCardsDic.TryGetValue(posId, out winnerCardsList))
				{
					foreach(var uCardsPair in userCardsDic)
					{
						var pos = uCardsPair.Key;
						var cardsList = uCardsPair.Value;
						if(pos != posId)
						{
							//先比较牌型
							if ((int)cardsType[pos] > (int)cardsType[posId])
							{
								isThisCardIsOuts = true;
								break;
							}
							else if((int)cardsType[pos] == (int)cardsType[posId])
							{
								if(CompareCard(cardsList.ToArray(), winnerCardsList.ToArray(), MAX_CENTERCOUNT) == 2) //前面一个是落后玩家,并且这时候大
								{
									isThisCardIsOuts = true;
									break;
								}
							}
						}
					}
				}
				else
				{
					Tool.WriteErrorLine("没有找到当前领先的玩家牌");
					return null;
				}

				if(isThisCardIsOuts)
				{
					outsList.Add(card);
				}
			}

			if(outsList.Count == 0)
			{
				Tool.WriteErrorLine("没有找到outs牌");
				return null;
			}
			return outsList;
		}

		/// <summary>
		/// 拼凑五张牌的组合
		/// </summary>
		/// <param name="cardDatas">所有玩家当前的手牌</param>
		/// <param name="tableCard">桌子牌的数量</param>
		/// <param name="cardCount">当前桌子牌的数量</param>
		/// <param name="backUpCardData">一副牌剩余的牌</param>
		/// <returns>返回所有玩家的五张牌数据</returns>
		public Dictionary<int, List<int>> CombineMinFiveCards(Dictionary<int, List<int>> cardDatas, List<int> tableCard, List<int> backUpCardData, out Dictionary<int, DeckType> cardType)
		{
			cardType = new Dictionary<int, DeckType>();
			var TempUserCards = new Dictionary<int, List<int>>();
			foreach (var pair in cardDatas)
			{
				var list = new List<int>();
				list.AddRange(pair.Value);
				TempUserCards.Add(pair.Key, list);
			}
			//桌子未发的牌
			var tempBackUpCardData = new List<int>();
			tempBackUpCardData.AddRange(backUpCardData);

			var newUserCards = new Dictionary<int, List<int>>();
			foreach (var pair in TempUserCards)
			{
				var list = new List<int>();
				list.AddRange(pair.Value);
				list.AddRange(tableCard);
				newUserCards.Add(pair.Key, list);
			}
			var cardCount = tableCard.Count;
			if (cardCount > 3)
			{
				Tool.WriteErrorLine("底牌数据不应该大于3");
				return null;
			}
			for (int i = 0; i < 3 - cardCount; i++)
			{
				foreach (var card in tempBackUpCardData) //所有的没有发的牌
				{
					var tempNewUserCards = this.CanAddCardIntoHandCards(newUserCards, card);
					if (tempNewUserCards != null)
					{
						newUserCards.Clear();
						newUserCards = tempNewUserCards;
						break;
					}
				}
			}
			foreach (var pair in newUserCards)
			{
				var tempCardData = new List<int>();
				tempCardData.AddRange(pair.Value);
				var tempCardDataArray = tempCardData.ToArray();
				this.SortCardList(ref tempCardDataArray, tempCardDataArray.Length);
				var type = GetCardsType(pair.Value.ToArray(), MAX_CENTERCOUNT);
				cardType.Add(pair.Key, type);
			}
			return newUserCards;
		}

		/// <summary>
		/// 获得牌型
		/// </summary>
		/// <param name="cardData"></param>
		/// <param name="cardCount"></param>
		/// <returns></returns>
		public DeckType GetCardsType(int[] cardData, int cardCount)
		{
			
			//数据校验
			if (cardCount != MAX_CENTERCOUNT)
			{
				return DeckType.None;
			}
			//排序
			this.SortCardList(ref cardData, cardData.Length);

			//同色
			var sameColor = true;
			//顺子
			var lineCard = true;
			var firstColor = GetCardColor(cardData[0]);
			var firstValue = GetCardSize(cardData[0]);

			//牌型分析
			for (int i = 1; i < cardCount; i++)
			{
				if (GetCardColor(cardData[i]) != firstColor)
					sameColor = false;
				if ((firstValue - GetCardSize(cardData[i])) != i)
					lineCard = false;
				if (sameColor == false && lineCard == false)
					break;
			}

			//最小同花顺
			if (lineCard == false && firstValue == 14)
			{
				int i = 1;
				for (i = 1; i < cardCount; i++)
				{
					var cardValue = this.GetCardSize(cardData[i]);
					if (firstValue != (cardValue + i + 11))
						break;
				}
				if (i == cardCount)
					lineCard = true;
			}

			//皇家同花顺
			if (((sameColor == true) && (lineCard == true) && this.GetCardSize(cardData[1]) == 13)) //第二张牌是K
			{
				return DeckType.KingSequence;
			}

			if (sameColor == true && lineCard == true)
			{
				return DeckType.FlushSequence;
			}

			//顺子类型
			if ((sameColor == false) && (lineCard == true))
			{
				return DeckType.Straight;
			}

			//同花类型
			if (sameColor == true && lineCard == false)
			{
				return DeckType.Flush;
			}

			this.SortCardList(ref cardData, cardData.Length);
			//扑克分析
			AnalyseResult analyseResult = new AnalyseResult(); ;
			this.AnalysebCardData(cardData, cardCount, ref analyseResult);

			//类型判断
			//金刚
			if (analyseResult.ForCount == 1)
			{
				return DeckType.Bomb;
			}
			if (analyseResult.TwoCount == 2)
			{
				return DeckType.TwoDouble;
			}
			if (analyseResult.TwoCount == 1 && analyseResult.ThreeCount == 1)
			{
				return DeckType.Calabash; //葫芦
			}
			if (analyseResult.ThreeCount == 1 && analyseResult.TwoCount == 0)
			{
				return DeckType.Three; //三条
			}
			if (analyseResult.TwoCount == 1 && analyseResult.OneCount == 3)
			{
				return DeckType.OneDouble;//一对
			}
			return DeckType.Single;//高牌类型
		}

		/// <summary>
		/// 5-7张牌里面选择最大的一组五张牌
		/// </summary>
		/// <param name="handCardData">手牌</param>
		/// <param name="handCardCount">手牌数量=2</param>
		/// <param name="centerCardData">桌子底牌 数量不固定</param>
		/// <param name="centerCardCount">说子底牌数量</param>
		/// <param name="lastCardData">最后最优的牌组</param>
		/// <param name="lastCardCount">最后最优的牌组数量=5</param>
		/// <returns></returns>
		public DeckType FiveFromOther(int[] handCardData, int handCardCount, int[] centerCardData, int centerCardCount, ref int[] lastCardData, int lastCardCount)
		{
			//两张手牌和其他牌
			var tempCardData = new int[centerCardCount + MAX_COUNT];
			//最后的五张牌组
			var tempLastCardData = new int[MAX_CENTERCOUNT];

			//搜集两张手牌
			for (int i = 0; i < handCardCount; i++)
			{
				tempCardData[i] = handCardData[i];
			}
			//搜集桌上的牌
			for (int j = 0; j < centerCardCount; j++)
			{
				tempCardData[handCardCount + j] = centerCardData[j];
			}

			//几张牌排序
			this.SortCardList(ref tempCardData, tempCardData.Length);

			//拷贝前五张牌
			for (int i = 0; i < MAX_CENTERCOUNT; i++)
			{
				lastCardData[i] = tempCardData[i];
			}

			var cardType = this.GetCardsType(lastCardData, MAX_CENTERCOUNT);
			var tmepCardType = DeckType.None;

			int iMax = centerCardCount - 2;
			int jMax = iMax + 1;
			int kMax = jMax + 1;
			int lMax = kMax + 1;
			int mMax = lMax + 1;

			for (int i = 0; i < iMax; i++)
			{
				for (int j = i + 1; j < jMax; j++)
				{
					for (int k = j + 1; k < kMax; k++)
					{
						for (int l = k + 1; l < lMax; l++)
						{
							for (int m = l + 1; m < mMax; m++)
							{
								//获得数据
								tempLastCardData[0] = tempCardData[i];
								tempLastCardData[1] = tempCardData[j];
								tempLastCardData[2] = tempCardData[k];
								tempLastCardData[3] = tempCardData[l];
								tempLastCardData[4] = tempCardData[m];

								//获取牌型
								tmepCardType = this.GetCardsType(tempLastCardData, tempLastCardData.Length);

								//牌型大小
								if (this.CompareCard(tempLastCardData, lastCardData, tempLastCardData.Length) == 2)
								{
									cardType = tmepCardType;
									for (int n = 0; n < MAX_CENTERCOUNT; n++)
									{
										lastCardData[n] = tempLastCardData[n];
									}
								}
							}
						}
					}
				}
			}
			return cardType;
		}

		/// <summary>
		/// 获得胜利的玩家
		/// </summary>
		/// <param name="cardData">所有没有弃牌的玩家的牌</param>
		/// <param name="endResult"></param>
		/// <param name="addScore">九个人的一个数组，每个人的下注总数</param>
		/// <returns></returns>
		public bool SelectMaxUser(List<int[]> cardData, ref UserWinList endResult, ref List<int> addScore)
		{
			int winnerID = 0;
			int i = 0;
			int length = cardData.Count;
			//遍历所有玩家的第一张牌
			for (i = 0; i < length; i++)
			{
				if (cardData[i][0] != 0)
				{
					winnerID = i;
					break;
				}
			}
			//过滤所有玩家手牌为空的情况
			if (i == length)
				return false;

			//查找最大用户
			int temp = winnerID;
			for (i = 0; i < length; i++)
			{
				int j = (i + temp) % length;
				if (cardData[j][0] == 0)
					continue;
				//获得前面一种类型比较大
				if (this.CompareCard(cardData[j], cardData[winnerID], MAX_CENTERCOUNT) > 1)
				{
					winnerID = j;   //这边存的是index
				}
			}

			//查找相同的数据
			//endResult.WinerList[endResult.SameCount++] = winnerID;   //报错
			endResult.WinerList.Add(winnerID);
			endResult.SameCount++;
			for (i = 0; i < length; i++)
			{
				if (i == winnerID || cardData[i][0] == 0)
					continue;
				if (CompareCard(cardData[i], cardData[winnerID], MAX_CENTERCOUNT) == 0)
				{
					//endResult.WinerList[endResult.SameCount++] = i;
					endResult.WinerList.Add(i);
					endResult.SameCount++;
				}
			}

			//从小到大
			if (endResult.SameCount > 1 && addScore != null)
			{
				var sameCount = endResult.SameCount;
				while ((sameCount--) > 0)
				{
					long tempScore = addScore[endResult.WinerList[sameCount]];
					for (int j = sameCount - 1; j >= 0; j--)
					{
						if (addScore[endResult.WinerList[j]] <= 0)
							return false;
						if (tempScore < addScore[endResult.WinerList[j]])
						{
							tempScore = addScore[endResult.WinerList[j]];
							int tempValue = endResult.WinerList[sameCount];
							endResult.WinerList[sameCount] = endResult.WinerList[j];
							endResult.WinerList[j] = tempValue;
						}
					}
				}
			}
			return true;
		}

		/// <summary>
		/// 排列扑克
		/// </summary>
		/// <param name="cardData"></param>
		/// <param name="cardCount"></param>
		public void SortCardList(ref int[] cardData, int cardCount)
		{
			var logicValue = new int[FULL_COUNT];
			for (int i = 0; i < cardCount; i++)
			{
				logicValue[i] = this.GetCardSize(cardData[i]);
			}

			//排序操作
			bool sorted = true;
			int tempData = 0;
			int last = cardCount - 1;
			do
			{
				sorted = true;
				for (int i = 0; i < last; i++)
				{
					if ((logicValue[i] < logicValue[i + 1]) || ((logicValue[i] == logicValue[i + 1]) && (cardData[i] < cardData[i + 1])))
					{
						//交换位置
						tempData = cardData[i];
						cardData[i] = cardData[i + 1];
						cardData[i + 1] = tempData;
						tempData = logicValue[i];
						logicValue[i] = logicValue[i + 1];
						logicValue[i + 1] = tempData;
						sorted = false;
					}
				}
				last--;
			} while (sorted == false);
		}

		/// <summary>
		/// 比较相同类型的扑克
		/// </summary>
		/// <param name="firstCards"></param>
		/// <param name="NextCards"></param>
		/// <param name="cardCount">数量</param>
		/// <returns>2:前面一种类型大  1:后面一种类型大  0:一样大</returns>
		public int CompareCard(int[] firstCards, int[] nextCards, int cardCount)
		{
			var type1 = this.GetCardsType(firstCards, cardCount);
			var type2 = this.GetCardsType(nextCards, cardCount);
			//类型
			//前面一个类型大
			if (type1 > type2)
				return 2;
			//后面一个类型大
			if (type1 < type2)
				return 1;

			//相同的类型
			switch (type1)
			{
				//高牌
				case DeckType.Single:
					{
						int i = 0;
						for (i = 0; i < cardCount; i++)
						{
							var nextCardValue = this.GetCardSize(nextCards[i]);
							var firstCardValue = this.GetCardSize(firstCards[i]);
							if (firstCardValue > nextCardValue)
								return 2;
							else if (firstCardValue < nextCardValue)
								return 1;
							else
								continue;
						}
						if (i == cardCount)
							return 0;
					}
					break;
				case DeckType.OneDouble:
				case DeckType.TwoDouble:
				case DeckType.Three:
				case DeckType.Bomb: //四条
				case DeckType.Calabash://葫芦
					{
						AnalyseResult analyseResultNext = new AnalyseResult();
						AnalyseResult analyseResultFirst = new AnalyseResult();
						this.AnalysebCardData(nextCards, cardCount, ref analyseResultNext);
						this.AnalysebCardData(firstCards, cardCount, ref analyseResultFirst);

						//四条数值
						if (analyseResultFirst.ForCount > 0)
						{
							var nextValue = analyseResultNext.ForLogicVolue[0];
							var firstValue = analyseResultFirst.ForLogicVolue[0];

							//比较四条
							if (firstValue != nextValue)
								return firstValue > nextValue ? 2 : 1;
							//比较单牌

							firstValue = analyseResultFirst.OneLogicVolue[0];
							nextValue = analyseResultNext.OneLogicVolue[0];
							if (firstValue != nextValue)
								return firstValue > nextValue ? 2 : 1;
							else
								return 0;
						}

						//三条数值
						if (analyseResultFirst.ThreeCount > 0)
						{
							var nextValue = analyseResultNext.ThreeLogicVolue[0];
							var firstValue = analyseResultFirst.ThreeLogicVolue[0];
							//比较三条
							if (firstValue != nextValue)
								return firstValue > nextValue ? 2 : 1;

							//葫芦类型
							if (type1 == DeckType.Calabash)
							{
								firstValue = analyseResultFirst.TwoLogicVolue[0];
								nextValue = analyseResultNext.TwoLogicVolue[0];
								if (firstValue != nextValue)
									return firstValue > nextValue ? 2 : 1;
								else
									return 0;
							}
							else //三条带单
							{
								int i = 0;
								for (i = 0; i < analyseResultFirst.OneCount; i++)
								{
									var cbNextValue = analyseResultNext.OneLogicVolue[i];
									var cbFirstValue = analyseResultFirst.OneLogicVolue[i];
									if (cbFirstValue > cbNextValue)
										return 2;
									else if (cbFirstValue < cbNextValue)
										return 1;
									else
										continue;
								}
								if (i == analyseResultFirst.OneCount)
									return 0;
							}
						}
						//对子数值
						int k = 0;
						for (k = 0; k < analyseResultFirst.TwoCount; k++)
						{
							var nextValue = analyseResultNext.TwoLogicVolue[k];
							var firstValue = analyseResultFirst.TwoLogicVolue[k];

							if (firstValue > nextValue)
								return 2;
							else if (firstValue < nextValue)
								return 1;
							else
								continue;
						}
						if (k == analyseResultFirst.TwoCount)
						{
							if (analyseResultFirst.OneCount == analyseResultNext.OneCount && analyseResultNext.OneCount > 0)
							{
								for (k = 0; k < analyseResultFirst.OneCount; k++)
								{
									var cbNextValue = analyseResultNext.OneLogicVolue[k];
									var cbFirstValue = analyseResultFirst.OneLogicVolue[k];
									if (cbFirstValue > cbNextValue)
										return 2;
									else if (cbFirstValue < cbNextValue)
										return 1;
									else
										continue;
								}
								if (k == analyseResultFirst.OneCount)
									return 0;
							}
						}
					}
					break;
				case DeckType.Straight://顺子
				case DeckType.FlushSequence://同花顺
					//case DeckType.KingSequence://皇家同花顺
					{
						var nextValue = this.GetCardSize(nextCards[0]);
						var firstValue = this.GetCardSize(firstCards[0]);

						//TODO:判断第一张牌跟第二张牌是否相差9

						if (firstValue == nextValue)
						{
							return 0;
						}
						return firstValue > nextValue ? 2 : 1;
					}
					break;
				case DeckType.Flush://同花
					{
						int i = 0;
						for (i = 0; i < cardCount; i++)
						{
							var nextValue = this.GetCardSize(nextCards[i]);
							var firstValue = this.GetCardSize(firstCards[i]);
							if (firstValue == nextValue)
								continue;
							return (firstValue > nextValue) ? 2 : 1;
						}
						if (i == cardCount)
							return 0;
					}
					break;
			}
			return 0;
		}
	}
}
